﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System;
using System.ComponentModel;
using System.Windows.Forms;
using NetJsWire.JsonRpcHandler;
using NetJsWire.JsonRpcHandler.Attributes;
using NetJsWire.JsonRpcHandler.Util;
using NetJsWire.Widgets.Config;
using Newtonsoft.Json.Linq;

namespace NetJsWire.Widgets.Ui.Form
{
    ///<summary>
    ///</summary>
    [Renderer( typeof( Renderers.Form.DateField ) )]
    public partial class DateField : DateTimePicker, IWidget, IFormField
    {
        private readonly IRenderer _renderer;
        private bool _allowBlank = true;
        private string _blankText = string.Empty;
        private IConfigOptions _configOptions;
        private string _emptyText = string.Empty;
        private bool _internalChange;
        private bool _isValid = true;
        private string _maxLengthText = string.Empty;
        private int _minLength;
        private string _minLengthText = string.Empty;
        private bool _sendUpdates = true;
        private string _text;

        ///<summary>
        ///  Default constructor
        ///</summary>
        public DateField()
        {
            InitializeComponent();
            _renderer = Helper.GetRenderer( this );
            Input += DateFieldInput;
        }

        /// <summary>
        ///   Default constructor with IContainer
        /// </summary>
        /// <param name = "container">The container to add to.</param>
        public DateField( IContainer container )
        {
            container.Add( this );
            InitializeComponent();
            _renderer = Helper.GetRenderer( this );
            Input += DateFieldInput;
        }

        /// <summary>
        ///   True if the value of the control is valid.
        /// </summary>
        public bool IsValid
        {
            get { return _isValid; }
            set { _isValid = value; }
        }

        [DefaultValue( ( string ) null )]
        public override string Text
        {
            get { return _text; }
            set
            {
                _text = value;
                if ( _isValid )
                {
                    DateTime tmp;
                    if ( DateTime.TryParse( value, out tmp ) )
                    {
                        Value = tmp;
                    }
                }
                //SetText(value);
                if ( Renderer.Rendered && !_internalChange )
                {
                    Renderer.CallCommand( "setValue", value );
                }
            }
        }

        ///<summary>
        ///  True if the control is enabled.
        ///</summary>
        [DefaultValue( true )]
        public new bool Enabled
        {
            get { return base.Enabled; }
            set
            {
                SetEnabled( value );
                if ( Renderer.Rendered )
                    Renderer.CallCommand( "setDisabled", !value );
                else
                {
                    if ( !value )
                        Renderer.SetConstructionProperty( "disabled", true );
                }
            }
        }

        ///<summary>
        ///  The text to show on the control tip when its value is blank and AllowBlank is set to false.
        ///</summary>
        [DefaultValue( ( string ) null )]
        public string BlankText
        {
            get { return _blankText; }
            set
            {
                _blankText = value;
                if ( Renderer.Rendered )
                {
                    Renderer.SetEqualProperty( "blankText", "\"" + value + "\"" );
                }
                else
                {
                    Renderer.SetConstructionProperty( "blankText", value );
                }
            }
        }

        //[DefaultValue(32767)]
        //public override int MaxLength
        //{
        //    get
        //    {
        //        return base.MaxLength;
        //    }
        //    set
        //    {
        //        base.MaxLength = value;
        //        if (Renderer.Rendered)
        //        {
        //            Renderer.SetEqualProperty("maxLength", value);
        //        }
        //        else
        //        {
        //            Renderer.SetConstructionProperty("maxLength", value);
        //        }
        //    }
        //}

        /// <summary>
        ///   The text to show in th control tip when the lenght of the value is long than MaxLenght
        /// </summary>
        [DefaultValue( ( string ) null )]
        public string MaxLengthText
        {
            get { return _maxLengthText; }
            set
            {
                _maxLengthText = value;
                if ( Renderer.Rendered )
                {
                    Renderer.SetEqualProperty( "maxLengthText", value );
                }
                else
                {
                    Renderer.SetConstructionProperty( "maxLengthText", value );
                }
            }
        }

        /// <summary>
        ///   The minimum lenght.
        /// </summary>
        [DefaultValue( 0 )]
        public int MinLength
        {
            get { return _minLength; }
            set
            {
                _minLength = value;
                if ( Renderer.Rendered )
                {
                    Renderer.SetEqualProperty( "minLength", value );
                }
                else
                {
                    Renderer.SetConstructionProperty( "minLength", value );
                }
            }
        }

        /// <summary>
        ///   The text to show in th control tip when the lenght of the value is shorther than MinLenght
        /// </summary>
        [DefaultValue( ( string ) null )]
        public string MinLengthText
        {
            get { return _minLengthText; }
            set
            {
                _minLengthText = value;
                if ( Renderer.Rendered )
                {
                    Renderer.SetEqualProperty( "minLengthText", value );
                }
                else
                {
                    Renderer.SetConstructionProperty( "minLengthText", value );
                }
            }
        }

        /// <summary>
        ///   True if the control allows Blank values.
        /// </summary>
        [DefaultValue( true )]
        public bool AllowBlank
        {
            get { return _allowBlank; }
            set
            {
                if ( Renderer.Rendered )
                {
                    Renderer.SetEqualProperty( "allowBlank", value );
                    Renderer.AddCommand( "validate", null );
                }
                else
                {
                    Renderer.SetConstructionProperty( "allowBlank", value );
                }
                _allowBlank = value;
            }
        }

        /// <summary>
        ///   The text to show on the control whne its empty, it will be shown as a watermark.
        /// </summary>
        [DefaultValue( ( string ) null )]
        public string EmptyText
        {
            get { return _emptyText; }
            set
            {
                _emptyText = value;
                if ( Renderer.Rendered )
                {
                    Renderer.SetEqualProperty( "emptyText", value );
                }
                else
                {
                    Renderer.SetConstructionProperty( "emptyText", value );
                }
            }
        }

        [DefaultValue( true )]
        public bool SendUpdates
        {
            get { return _sendUpdates; }
            set { _sendUpdates = value; }
        }

        public bool InternalChange
        {
            get { return _internalChange; }
            set { _internalChange = value; }
        }

        #region IFormField Members

        [DefaultValue( ( string ) null )]
        public string FieldLabel { get; set; }

        #endregion

        #region IWidget Members

        [Browsable( false ), EditorBrowsable( EditorBrowsableState.Advanced )]
        public IRenderer Renderer
        {
            get { return _renderer; }
        }

        public void On( string name, string function )
        {
            Renderer.AddClientEvent( name, function );
        }

        public void AddClass( string cls )
        {
            Renderer.AddCommand( "addClass", cls );
        }

        public void RemoveClass( string cls )
        {
            Renderer.AddCommand( "removeClass", cls );
        }

        [DefaultValue( false )]
        [Description(
           "If the framework should generate a global Javascript variable that points to the Widget, the name of the variable will be the same as ClientID property of the Renderer."
           )]
        public bool GenerateClientMember { get; set; }

        [RefreshProperties( RefreshProperties.All ),
         DesignerSerializationVisibility( DesignerSerializationVisibility.Content ), Category( "Config" )]
        public IConfigOptions ConfigOptions
        {
            get
            {
                if ( _configOptions == null )
                {
                    _configOptions = new FieldConfigOptions( this ) { Xtype = "ndatefield" };
                }
                return _configOptions;
            }
        }

        #endregion

        public event EventHandler Input;
        public new event EventHandler TextChanged;

        private void DateFieldInput( object sender, EventArgs e )
        {
            _internalChange = true;
            var vals = ( JArray ) sender;
            //SetText(vals[0].ToString());
            _isValid = ( bool ) vals[ 1 ];
            Text = vals[ 0 ].ToString();
            object oTch = TextChanged;
            if ( oTch != null )
                TextChanged( this, null );
            _internalChange = false;
        }

        private void SetEnabled( bool enabled )
        {
            if ( InvokeRequired )
            {
                var d = new SetEnabledCallback( SetEnabled );
                BeginInvoke( d, new object[] { enabled } );
            }
            else
            {
                base.Enabled = enabled;
            }
        }

        public new void Focus()
        {
            Renderer.AddCommand( "focus", null );
        }

        #region Nested type: SetEnabledCallback

        private delegate void SetEnabledCallback( bool enabled );

        #endregion
    }
}